from flask import current_app
from flask_httpauth import HTTPTokenAuth, MultiAuth
from flask_restx import abort

from app.models import userModel
from tools.basic_tools import Tools
from configs.settings import flask_config
from tools import redis_conn

from .time_jws import TimedJSONWebSignatureSerializer as Serializer

token_auth = HTTPTokenAuth(scheme="Bearer")
auth = MultiAuth(token_auth)


def verify_password(email_or_username, password) -> tuple:
    try:
        user = userModel.User.query.filter_by(username=email_or_username).first()
        if not user:
            return False, "用户不存在"
        if not user.verify_password(password):
            return False, "密码错误"
        token = create_token(user.id)
        return True, {
            "id": user.id,
            "username": user.username,
            "role": user.role_id,
            "roles": sorted(item.name for item in user.roles),
            "is_superuser": user.is_superuser,
            "realname": user.account_name,
            "token": token,
            "user_only": Tools.get_uuid4_no_line()
        }
    except Exception as e:
        current_app.logger.exception(e)
        print(e)
        return False, "登录失败"


@token_auth.verify_token
def verify_token(token):
    serializer = Serializer(flask_config.secret_key)
    try:
        data = serializer.loads(token)
    except Exception as e:
        current_app.logger.exception(e)
        return False
    user = userModel.User.query.get(data["id"])
    if user and redis_conn.get(f"LoginUsername_{user.username}"):
        return user
    abort(401, message="登录失效，请重新登录")


def create_token(user_id):
    s = Serializer(flask_config.secret_key, expires_in=flask_config.EXPIRATION)
    return s.dumps({"id": user_id}).decode("ascii")
